/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.sgsmcan.Controlador;

import com.sgsmcan.Dao.EventoDao;
import com.sgsmcan.Dao.EventoDaoImpl;
import com.sgsmcan.Dao.EventoFrecuenteDao;
import com.sgsmcan.Dao.EventoFrecuenteImpl;
import com.sgsmcan.Dao.EventoSerenoPerroDao;
import com.sgsmcan.Dao.EventoSerenoPerroImpl;
import com.sgsmcan.Dao.SerenoPerroDao;
import com.sgsmcan.Dao.SerenoPerroImpl;
import com.sgsmcan.Dao.TipoEventoDao;
import com.sgsmcan.Dao.TipoEventoDaoImpl;
import com.sgsmcan.Entidad.Evento;
import com.sgsmcan.Entidad.EventoFrecuente;
import com.sgsmcan.Entidad.EventoSerenoPerro;
import com.sgsmcan.Entidad.EventoSerenoPerroId;
import com.sgsmcan.Entidad.SerenoPerro;
import com.sgsmcan.Entidad.TipoEvento;
import com.sgsmcan.Utils.Utilitario;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import org.primefaces.context.RequestContext;
import org.primefaces.event.ScheduleEntryMoveEvent;
import org.primefaces.event.ScheduleEntryResizeEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.DefaultScheduleEvent;
import org.primefaces.model.DefaultScheduleModel;
import org.primefaces.model.ScheduleEvent;
import org.primefaces.model.ScheduleModel;

/**
 *
 * @author David
 */
@ManagedBean(name = "eventoBean")
@ViewScoped
public final class EventoControlador implements Serializable {

    private ScheduleModel eventModel = new DefaultScheduleModel();
    private ScheduleEvent event = new DefaultScheduleEvent();
    private List<TipoEvento> lstTipoEventos;
    private List<SerenoPerro> serenosperros;
    private List<SerenoPerro> serenosAsignados;
    private EventoDao eventoDao;
    private TipoEventoDao tipoEventoDao;
    private SerenoPerroDao serenoPerroDao;
    private EventoFrecuenteDao eventoFrecuenteDao;
    private EventoSerenoPerroDao eventoSerenoPerroDao;
    private TipoEvento tipoEvento;
    private EventoFrecuente eventoFrecuente;
    private List<TipoEvento> listTipoEvento;
    private List<EventoFrecuente> lstEventoFrecuente;
    private String ubicacion;
    private boolean modificar;
    private boolean modificar_aux;
    private boolean select;
    private boolean traerSereno;

    public EventoControlador() {
        eventoDao = new EventoDaoImpl();
        tipoEventoDao = new TipoEventoDaoImpl();
        tipoEvento = new TipoEvento();
        eventModel = new DefaultScheduleModel();
        serenoPerroDao = new SerenoPerroImpl();
        eventoSerenoPerroDao = new EventoSerenoPerroImpl();
        eventoFrecuenteDao = new EventoFrecuenteImpl();
        serenosAsignados = new ArrayList<SerenoPerro>();
        eventoFrecuente = new EventoFrecuente();
    }

    public void init() {
        if (!FacesContext.getCurrentInstance().isPostback()) {
            llenarEventos(eventoDao.getEventos(), eventModel);
            eventoFrecuenteDao.getEventos();
            lstTipoEventos = tipoEventoDao.getTiposEventos();
            lstEventoFrecuente = eventoFrecuenteDao.getEventos();
        }

    }

    public String devolverDescripcionEvento(int id) {
        for (TipoEvento te : lstTipoEventos) {
            if (te.getIdTipoEvento() == id) {
                return te.getDescripcion();
            }
        }
        return "Error";
    }

    public void llenarEventos(List<Evento> lstEvento, ScheduleModel eventModel) {
        eventModel = eventModel.getEventCount() != 0 ? new DefaultScheduleModel() : eventModel;
        Date date = new Date();
        for (Evento e : lstEvento) {
            DefaultScheduleEvent evento = new DefaultScheduleEvent();
            evento.setTitle(e.getNombre());
            evento.setStartDate(e.getFechaEvento());
            evento.setEndDate(e.getFechaEventoFin());
            evento.setEditable(e.getFechaEvento().after(date));
            evento.setData(e);
            eventModel.addEvent(evento);
        }
    }

    public void capturarEventoFrecuente(EventoFrecuente ef) {
        eventoFrecuente = ef;
    }

    ////METODOS PARA EL CALENDARIO ///
    public boolean validaEventoAux() {
        if (eventoFrecuente != null) {
            if (eventoFrecuente.getIdTipo() != null
                    && eventoFrecuente.getNombre() != null
                    && eventoFrecuente.getIdTipo() != null) {
                return true;
            }
        }
        return false;
    }

    public void onDateSelect(SelectEvent selectEvent) {
        Date date = (Date) selectEvent.getObject();
        String title = "";
        if (date.after(new Date())) {
            if (validaEventoAux()) {
                title = eventoFrecuente.getNombre();
                tipoEvento.setIdTipoEvento(eventoFrecuente.getIdTipo());
            }
            event = new DefaultScheduleEvent(title, date, date);
            modificar = false;
            modificar_aux = false;
            RequestContext requestContext = RequestContext.getCurrentInstance();
            requestContext.execute("eventDialog.show()");
        }
        traerSereno = false;
    }

    public void onEventSelect(SelectEvent selectEvent) {
        event = (ScheduleEvent) selectEvent.getObject();
        modificar = event.getStartDate().before(new Date());
        Evento e = (Evento) event.getData();
        tipoEvento = e.getTipo();
        ubicacion = e.getUbicacion();
        modificar_aux = true;
        traerSereno = false;
    }

    public void onEventMove(ScheduleEntryMoveEvent scheduleEntryMoveEvent) {
        event = scheduleEntryMoveEvent.getScheduleEvent();
        actualizarEvento_aux(event);
    }

    public void onEventResize(ScheduleEntryResizeEvent scheduleEntryResizeEvent) {
        event = scheduleEntryResizeEvent.getScheduleEvent();
        actualizarEvento_aux(event);
    }

    public void actualizarEvento_aux(ScheduleEvent event) {
        try {
            Evento e = (Evento) event.getData();
            FechaEvento(e, event);
            eventoDao.actualizar(e);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void agregarEvento() {
        if (!isValido()) {
            return;
        }
        Evento evento = !modificar_aux ? new Evento() : (Evento) event.getData();
        evento.setNombre(event.getTitle());
        FechaEvento(evento, event);
        evento.setTipo(tipoEvento);
        evento.setUbicacion(ubicacion);
        try {
            if (modificar_aux) {
                eventoDao.actualizar(evento);
            } else {
                eventoDao.insertar(evento);
                DefaultScheduleEvent ev = new DefaultScheduleEvent();
                ev = (DefaultScheduleEvent) event;
                ev.setData(evento);
                eventModel.addEvent(ev);
            }
            agregarEventoSerenoCan(evento.getIdEvento());
            RequestContext requestContext = RequestContext.getCurrentInstance();
            requestContext.execute("eventDialog.hide()");
            serenosAsignados = new ArrayList();
        } catch (Exception e) {
            Utilitario.enviarMensajeGlobalError("Ocurrio un error inesperado");
            e.printStackTrace();
        }
    }

    public void agregarEventoSerenoCan(int nidEvento) {
        for (SerenoPerro sp : serenosAsignados) {
            if (!sp.isEstado()) {
                EventoSerenoPerro esp = new EventoSerenoPerro();
                EventoSerenoPerroId espi = new EventoSerenoPerroId();
                espi.setEventoId(nidEvento);
                espi.setSerenoHasPerroIdPerro(sp.getPerro().getId());
                espi.setSerenoHasPerroIdSereno(sp.getSereno().getId());
                esp.setEsp(espi);
                eventoSerenoPerroDao.insertar(esp);
            }
        }

    }

    public void FechaEvento(Evento evento, ScheduleEvent event) {
        evento.setFechaEvento(new Timestamp(event.getStartDate().getTime()));
        evento.setFechaEventoFin(new Timestamp(event.getEndDate().getTime()));
    }

    ///FIN/////////////////////////////
    public void agregarFrecuente() {
        if (!isValidoF()) {
            return;
        }
        try {
            eventoFrecuenteDao.insertar(eventoFrecuente);
            RequestContext requestContext = RequestContext.getCurrentInstance();
            requestContext.execute("dialogEve.hide()");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void traerSerenosAsignados(int idEvento) {
        List<EventoSerenoPerro> lst = eventoSerenoPerroDao.getEventoSerenoPerroByEvento(idEvento);
        serenosAsignados = new ArrayList();
        for (EventoSerenoPerro esp : lst) {
            serenosAsignados.add(esp.getSerenoPerro());
        }
    }

    public void seleccionarSereno(SerenoPerro sereno) {
        if (isSelecionado(sereno.getSereno().getId())) {
            return;
        }
        sereno.setEstado(false);
        serenosAsignados.add(sereno);
    }

    public void eliminarSereno(SerenoPerro sereno) {
        serenosAsignados.remove(sereno);
        if (event.getData() != null && sereno.isEstado()) {
            Evento e = (Evento) event.getData();
            EventoSerenoPerro esp = new EventoSerenoPerro();
            EventoSerenoPerroId id = new EventoSerenoPerroId();
            id.setEventoId(e.getIdEvento());
            id.setSerenoHasPerroIdPerro(sereno.getPerro().getId());
            id.setSerenoHasPerroIdSereno(sereno.getSereno().getId());
            esp.setEsp(id);
            eventoSerenoPerroDao.eliminar2(esp);
            FechaEvento(e, event);
            serenosperros = serenoPerroDao.getSerenoPerroDisponible(e.getFechaEvento(), e.getFechaEventoFin());
        }
    }

    private boolean isSelecionado(int id) {
        for (SerenoPerro sp : serenosAsignados) {
            if (sp.getSereno().getId() == id) {
                return true;
            }
        }
        return false;
    }

    public boolean isValido() {
        if (!esTituloValido()) {
            return false;
        }
        if (!esTipoEventoValido()) {
            return false;
        }
        if (!esFechaEventoValida()) {
            return false;
        }
        return true;
    }

    public boolean isValidoF() {
        if (!esTituloValidoF()) {
            return false;
        }
        if (!esTipoEventoValidoF()) {
            return false;
        }
        return true;
    }

    public boolean esTituloValido() {
        if (Utilitario.esNulo(event.getTitle())) {
            Utilitario.enviarMensajeGlobalError("Debe ingresar el nombre del Evento");
            return false;
        } else if (!Utilitario.esRangoValido(event.getTitle(), 80)) {
            Utilitario.enviarMensajeGlobalError("El maximo de caracteres del nombre del Evento es 80");
            return false;
        }
        return true;
    }

    public boolean esTituloValidoF() {
        if (Utilitario.esNulo(eventoFrecuente.getNombre())) {
            Utilitario.enviarMensajeGlobalError("Debe ingresar el nombre del Evento");
            return false;
        } else if (!Utilitario.esRangoValido(eventoFrecuente.getNombre(), 80)) {
            Utilitario.enviarMensajeGlobalError("El maximo de caracteres del nombre del Evento es 80");
            return false;
        }
        return true;
    }

    public boolean esTipoEventoValido() {
        if (tipoEvento.getIdTipoEvento() == 0) {
            Utilitario.enviarMensajeGlobalError("Selecione el tipo de evento");
            return false;
        }
        return true;
    }

    public boolean esTipoEventoValidoF() {
        if (eventoFrecuente.getIdTipo() == 0) {
            Utilitario.enviarMensajeGlobalError("Selecione el tipo de evento");
            return false;
        }
        return true;
    }

    public boolean esFechaEventoValida() {
        Date date = new Date();
        if (date.after(event.getStartDate())) {
            Utilitario.enviarMensajeGlobalError("Las fechas a registrar deben ser mayor a la actual");
            return false;
        }
        if (event.getStartDate().equals(event.getEndDate()) || event.getStartDate().after(event.getEndDate())) {
            Utilitario.enviarMensajeGlobalError("La fecha Fin debe ser posterior a la fecha de Inicio");
            return false;
        }
        return true;
    }

    public void fechaValida_aux() {
        try {
            if (modificar) {
                Evento e = (Evento) event.getData();
                traerSerenosAsignados(e.getIdEvento());
                RequestContext requestContext = RequestContext.getCurrentInstance();
                requestContext.execute("serenoDialog2.show()");
                return;
            }
            if (esFechaEventoValida()) {
                Evento e = (Evento) event.getData();
                if (e != null && !traerSereno) {
                    traerSerenosAsignados(e.getIdEvento());
                    traerSereno = true;
                } else {
                    e = new Evento();
                }
                FechaEvento(e, event);
                serenosperros = serenoPerroDao.getSerenoPerroDisponible(e.getFechaEvento(), e.getFechaEventoFin());
                RequestContext requestContext = RequestContext.getCurrentInstance();
                requestContext.execute("serenoDialog.show()");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void eliminarEvento() {
        Evento e = (Evento) event.getData();
        List<EventoSerenoPerro> lst = eventoSerenoPerroDao.getEventoSerenoPerroByEvento(e.getIdEvento());
        for (EventoSerenoPerro esp : lst) {
            eventoSerenoPerroDao.eliminar2(esp);
        }
        eventoDao.eliminar2(e);
        eventModel.deleteEvent(event);
    }

    public ScheduleModel getEventModel() {
        return eventModel;
    }

    public void setEventModel(ScheduleModel eventModel) {
        this.eventModel = eventModel;
    }

    public ScheduleEvent getEvent() {
        return event;
    }

    public void setEvent(ScheduleEvent event) {
        this.event = event;
    }

    public TipoEvento getTipoEvento() {
        return tipoEvento;
    }

    public void setTipoEvento(TipoEvento tipoEvento) {
        this.tipoEvento = tipoEvento;
    }

    public List<TipoEvento> getLstTipoEventos() {
        return lstTipoEventos;
    }

    public void setLstTipoEventos(List<TipoEvento> lstTipoEventos) {
        this.lstTipoEventos = lstTipoEventos;
    }

    public boolean isModificar() {
        return modificar;
    }

    public void setModificar(boolean modificar) {
        this.modificar = modificar;
    }

    public List<SerenoPerro> getSerenosperros() {
        return serenosperros;
    }

    public void setSerenosperros(List<SerenoPerro> serenosperros) {
        this.serenosperros = serenosperros;
    }

    public boolean isModificar_aux() {
        return modificar_aux;
    }

    public void setModificar_aux(boolean modificar_aux) {
        this.modificar_aux = modificar_aux;
    }

    public boolean isSelect() {
        return select;
    }

    public void setSelect(boolean select) {
        this.select = select;
    }

    public List<SerenoPerro> getSerenosAsignados() {
        return serenosAsignados;
    }

    public void setSerenosAsignados(List<SerenoPerro> serenosAsignados) {
        this.serenosAsignados = serenosAsignados;
    }

    public String getUbicacion() {
        return ubicacion;
    }

    public void setUbicacion(String ubicacion) {
        this.ubicacion = ubicacion;
    }

    public TipoEventoDao getTipoEventoDao() {
        return tipoEventoDao;
    }

    public void setTipoEventoDao(TipoEventoDao tipoEventoDao) {
        this.tipoEventoDao = tipoEventoDao;
    }

    public List<EventoFrecuente> getLstEventoFrecuente() {
        return lstEventoFrecuente;
    }

    public void setLstEventoFrecuente(List<EventoFrecuente> lstEventoFrecuente) {
        this.lstEventoFrecuente = lstEventoFrecuente;
    }

    public List<TipoEvento> getListTipoEvento() {
        return listTipoEvento;
    }

    public void setListTipoEvento(List<TipoEvento> listTipoEvento) {
        this.listTipoEvento = listTipoEvento;
    }

    public EventoFrecuente getEventoFrecuente() {
        return eventoFrecuente;
    }

    public void setEventoFrecuente(EventoFrecuente eventoFrecuente) {
        this.eventoFrecuente = eventoFrecuente;
    }

    public boolean isTraerSereno() {
        return traerSereno;
    }

    public void setTraerSereno(boolean traerSereno) {
        this.traerSereno = traerSereno;
    }

}
